package com.xuzy.x808.common.utils;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class SendUtils {
    /**
     * 平台通用回复  标识位 消息头 消息体 检验码 标识位
     * <p>
     * 除了通用回复的内容，还需要包上消息头，接收到的和返回的消息头是一样的：
     * <p>
     * 起始字节 字段 数据类型 描述及要求
     * 0 消息 ID WORD
     * 2 消息体属性 WORD 消息体属性格式结构图见图 2
     * 4 终端手机号 BCD[6]  根据安装后终端自身的手机号转换。手机号不足12位，则在前补充数字，大陆手机号补充数字0，港澳台则根据其区号进行位数补充
     * 10 消息流水号 WORD 按发送顺序从 0 开始循环累加
     * 12 消息包封装项 如果消息体属性中相关标识位确定消息分包处理
     * 则该项有内容，否则无该项
     *
     * @param devId
     * @param msgBody
     * @return
     */
    public static ByteBuf packetNormalResponse(String devId, int msgId, ByteBuf msgBody) {
        ByteBuf response = Unpooled.buffer(1024);
        //-消息头 开始
        response.writeShort(msgId);
        //--消息体属性 开始
        response.writeShort(msgBody.readableBytes());
        //--消息体属性 结束
        response.writeBytes(ByteUtils.strToBcd(devId));
        response.writeShort(1);
        //-消息头 结束
        //-消息体开始
        response.writeBytes(msgBody);

        //-消息体结束
        //-检验码
        response.writeByte(crc(response));
        return transfer0x7e(response);
    }

    /**
     * 校验位 校验码指从消息头开始，同后一字节异或，直到校验码前一个字节，占用一个字节。
     *
     * @return
     */
    public static byte crc(ByteBuf byteBuf) {
        ByteBuf buf = byteBuf.copy();
        byte checksum = 0;
        while (buf.readableBytes() > 0) {
            checksum ^= buf.readUnsignedByte();
        }
        return checksum;
    }

    /**
     * 输出前，同样要跟输入时一样做个转义
     *
     * @param byteBuf
     * @return
     */
    private static ByteBuf transfer0x7e(ByteBuf byteBuf) {
        ByteBuf response = Unpooled.buffer(1024);
        response.writeByte(0x7e);
        for (Integer i = 0; i < byteBuf.readableBytes(); i++) {
            byte data = byteBuf.getByte(i);
            if (data == 0x7e) {
                response.writeByte(0x7d);
                response.writeByte(0x02);
            } else if (data == 0x7d) {
                response.writeByte(0x7d);
                response.writeByte(0x01);
            } else {
                response.writeByte(data);
            }
        }
        response.writeByte(0x7e);
        return response;
    }
}
